#include <iostream>
#include <functional>
#include <assert.h>

#include "lambda/lambda.hpp"

using namespace night::lambda;

int product_2 (int a, int b) { return a*b; }

template<class L>
int call_with_100 ( L const & f ) { return f ( ref(100) ); }

struct Foo {
	typedef int result_type;
	int operator () (int x) const { return x*x*x; }
} const foo = Foo ();

int main ()
{
	arg<1> fn;

	int i=1, j=2;

	assert ( ( fun (fn,y,z) [ fn[y,z] ] (fun (x,y) [x+y],i,j) ) == 3 );
	assert ( ( fun (fn,y) [ fn[y] ] (foo,j) ) == 8 );
	assert ( ( fun (fn,y,z) [ fn[y,z] ] (product_2,i,j) ) == 2 );

	assert ( call_with_100 ( x+1 ) == 101 );
	assert (( fun (fn,y,z) [ fn[y,z] ] ( ref(std::plus<int>()),i,i ) == 2 ));

}

